package com.onpositive.dataminer.core;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;

import com.onpositive.dataminer.value.transformers.WikiLinksRedirectionTransformer;
import com.onpositive.knowledge.model.inference.InferTransformer;
import com.onpositive.knowledge.model.values.ActualDocumentsTransformer;
import com.onpositive.knowledge.model.values.CompositeTransformer;
import com.onpositive.knowledge.model.values.IHasAuditResult;
import com.onpositive.knowledge.model.values.IValueTransformer;
import com.onpositive.knowledge.model.values.IdentPropertyTransformer;
import com.onpositive.knowledge.model.values.IdentValueSplitterTransformer;
import com.onpositive.knowledge.model.values.MergeIdenticalTransformer;
import com.onpositive.knowledge.model.values.PredictionTransformer;
import com.onpositive.knowledge.model.values.ReplacementTransformer;
import com.onpositive.knowledge.model.values.StatisticValueTransformer;
import com.onpositive.knowledge.model.values.ValueSequenceOrderingTransformer;
import com.onpositive.knowledge.model.values.WikiLinksRefiningTransformer;

public class DefaultTransformerFactory {
	
	public static IValueTransformer getTransformer( String ID, IHasAuditResult hasRes, Object... cArgs )
	{		
		DefaultTransformerFactory fabric = new DefaultTransformerFactory() ;
		return fabric.constructObject( ID, hasRes, cArgs );
	}
	
	
	private HashMap<String,Constructor<?>> map = new HashMap<String, Constructor<?>>() ;
	{
		try {
			map.put( IdentPropertyTransformer.ID, IdentPropertyTransformer.class.getConstructor( IHasAuditResult.class ) ) ;
			map.put( IdentValueSplitterTransformer.ID, IdentValueSplitterTransformer.class.getConstructor( IHasAuditResult.class ) ) ;
			map.put( ActualDocumentsTransformer.ID, ActualDocumentsTransformer.class.getConstructor( IHasAuditResult.class ) ) ;
			map.put( PredictionTransformer.ID, PredictionTransformer.class.getConstructor( IHasAuditResult.class ) ) ;
			map.put( ReplacementTransformer.ID, ReplacementTransformer.class.getConstructor( IHasAuditResult.class, String.class ) ) ;
			map.put( StatisticValueTransformer.ID, StatisticValueTransformer.class.getConstructor( IHasAuditResult.class ) ) ;
			map.put( ValueSequenceOrderingTransformer.ID, ValueSequenceOrderingTransformer.class.getConstructor( IHasAuditResult.class ) ) ;
			map.put( WikiLinksRefiningTransformer.ID, WikiLinksRefiningTransformer.class.getConstructor( IHasAuditResult.class ) ) ;
			map.put( WikiLinksRedirectionTransformer.ID, WikiLinksRedirectionTransformer.class.getConstructor( IHasAuditResult.class ) ) ;
			
			map.put( CompositeTransformer.ID, CompositeTransformer.class.getConstructor() ) ;
			map.put( InferTransformer.ID, InferTransformer.class.getConstructor() ) ;
			map.put( MergeIdenticalTransformer.ID, MergeIdenticalTransformer.class.getConstructor() ) ;
//			map.put( SimpleValueTransformer.ID, SimpleValueTransformer.class.getConstructor() ) ;  smpth. weird
			
			
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
	}
	
	private IValueTransformer constructObject(String ID, IHasAuditResult hasRes, Object...cArgs)
	{
		Constructor<?> constr = map.get(ID) ;
		if( constr == null )
			return null ;
		
		try {
			Object obj ;
			if( constr.getParameterTypes().length == 0 )
				 obj = constr.newInstance() ;
			else
				if(cArgs!=null&&cArgs.length!=0){
					obj = constr.newInstance( hasRes, cArgs[0] ) ;
				}
				else{
					obj = constr.newInstance( hasRes) ;
				}
			
			if( !(obj instanceof IValueTransformer ) )
				return null ;
			
			return (IValueTransformer) obj ;
			
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null ;
	}
}

